#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<pthread.h>
#include<unistd.h>
#include<fcntl.h>
#include<signal.h>
#include<ctype.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/select.h>
//需求使用多线程提高服务器的并发量
#define SERVICEPORT 9527
void sys_error(const char*s){
     perror(s);
     exit(-1);
}
int main(){
   int listenfd,connfd,maxfd=0,addr_len;
   char buf[1024];
   struct sockaddr_in saddr,caddr;
   saddr.sin_port=htons(SERVICEPORT);
   saddr.sin_addr.s_addr=htonl(INADDR_ANY);
   saddr.sin_family=AF_INET;
   listenfd=socket(AF_INET,SOCK_STREAM,0);
   if(listenfd==-1){
      sys_error("socket is error");
   }
   bind(listenfd,(struct sockaddr*)&saddr,sizeof(saddr));
   listen(listenfd,128);
   fd_set rset,allset;
   FD_ZERO(&allset);//清空文件描述符
   FD_SET(listenfd,&allset);//将listenfd放入集合中
   maxfd=listenfd;
   int ret;
   while(1){
      rset=allset;
      ret=select(maxfd+1,&rset,NULL,NULL,NULL);//监控
      printf("ret value:%d\n",ret);
      if(ret<0){
         sys_error("select is error");
      }
      if(FD_ISSET(listenfd,&rset)){//当有新的连接在读的集合中 
        addr_len=sizeof(caddr);
        connfd=accept(listenfd+1,(struct sockaddr*)&caddr,&addr_len);
        FD_SET(connfd,&allset);//将取得连接的文件描述符放入tempset中
        if(maxfd<connfd){
	  maxfd=connfd;
        }
        if(ret==1){//说明select只返回一个 并且是listenfd 后续无需执行
           continue;
        }
      }
      int i,n,j;
      for(i=listenfd+1;i<=maxfd;i++){
         if(FD_ISSET(i,&rset)){
             n=read(i,buf,sizeof(buf));
	     if(n==0){
                close(i);
		FD_CLR(i,&allset);
	     }else if(n==-1){
                sys_error("read error");
	     }
	     write(STDOUT_FILENO,buf,n);	 
	 for(j=0;j<n;j++){
             buf[j]=toupper(buf[j]);
	 }
	 write(i,buf,n);
         write(STDOUT_FILENO,buf,n);
	}
      }
   } 
   close(listenfd);
   return 0;
}
